package com.socialsoftware.MediaCommunication.activity;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.view.View;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import com.google.android.material.button.MaterialButton;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.permissionx.guolindev.PermissionX;
import com.socialsoftware.MediaCommunication.model.CallMode;
import com.socialsoftware.MediaCommunication.model.CommunicationMessage;
import com.socialsoftware.MediaCommunication.model.MessageType;
import com.socialsoftware.MediaCommunication.service.WebSocketService;
import com.socialsoftware.MediaCommunication.utils.Constants;
import com.socialsoftware.MediaCommunication.webrtc.WebRTCManager;
import com.socialsoftware.R;
import org.json.JSONException;
import org.webrtc.SurfaceViewRenderer;
import org.webrtc.VideoTrack;
/**
 * Activity for video/audio chat
 */
public class VideoChatActivity extends AppCompatActivity implements WebRTCManager.WebRTCListener {
    private static final String TAG = "VideoChatActivity";
    private SurfaceViewRenderer localVideoView;
    private SurfaceViewRenderer remoteVideoView;
    private TextView tvRemoteUser;
    private MaterialButton btnCall;
    private MaterialButton btnHangup;
    private MaterialButton btnSwitchCamera;
    private ConstraintLayout callingLayout;
    private TextView tvCallingStatus;
    private TextView tvCalleeName;
    private TextView tvCallingType;
    private ProgressBar progressCalling;
    private FloatingActionButton btnCancelCall;
    private WebSocketService webSocketService;
    private WebRTCManager webRTCManager;
    private boolean isWebSocketServiceBound = false;
    private String callMode;
    private boolean isIncomingCall = false;
    private String targetUser;
    private String targetUsername;
    private final ServiceConnection webSocketServiceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            WebSocketService.WebSocketBinder binder = (WebSocketService.WebSocketBinder) service;
            webSocketService = binder.getService();
            isWebSocketServiceBound = true;
            webRTCManager = new WebRTCManager(VideoChatActivity.this, webSocketService, VideoChatActivity.this);
            webRTCManager.setCallMode(callMode);
            webRTCManager.init();
            initVideoViews();
            if (isIncomingCall && targetUser != null) {
                showVideoUI();
                webRTCManager.answerCall(targetUser, callMode);
            } else if (targetUser != null) {
                showCallingUI();
                webRTCManager.startCall(targetUser);
            }
        }
        @Override
        public void onServiceDisconnected(ComponentName name) {
            webSocketService = null;
            isWebSocketServiceBound = false;
        }
    };
    private final BroadcastReceiver webSocketReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (Constants.ACTION_WEBSOCKET_MESSAGE.equals(intent.getAction())) {
                String messageJson = intent.getStringExtra(Constants.EXTRA_MESSAGE_JSON);
                handleWebSocketMessage(messageJson);
            }
        }
    };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.videochat_activity);
        targetUser = getIntent().getStringExtra("contact_username");
        targetUsername = getIntent().getStringExtra("contact_name");
        if (targetUsername == null) {
            targetUsername = targetUser; // 如果没有名称，使用用户名作为显示名称
        }
        isIncomingCall = getIntent().getBooleanExtra("isIncoming", false);
        if (isIncomingCall) {
            targetUser = getIntent().getStringExtra(Constants.EXTRA_CALLER_NAME);
            targetUsername = targetUser;
        }
        callMode = getIntent().getStringExtra(Constants.EXTRA_CALL_MODE);
        if (callMode == null) {
            callMode = getIntent().getBooleanExtra("isVideoEnabled", true) ? 
                    CallMode.VIDEO.getValue() : CallMode.AUDIO.getValue();
        }
        initViews();
        checkPermissions();
        if (CallMode.VIDEO.getValue().equals(callMode)) {
            setTitle("视频通话");
            tvCallingType.setText("视频通话");
        } else {
            setTitle("语音通话");
            tvCallingType.setText("语音通话");
            localVideoView.setVisibility(View.GONE);
            remoteVideoView.setVisibility(View.GONE);
            btnSwitchCamera.setVisibility(View.GONE);
        }
    }
    private void initViews() {
        localVideoView = findViewById(R.id.local_video);
        remoteVideoView = findViewById(R.id.remote_video);
        tvRemoteUser = findViewById(R.id.tv_remote_user);
        btnCall = findViewById(R.id.btn_call);
        btnHangup = findViewById(R.id.btn_hangup);
        btnSwitchCamera = findViewById(R.id.btn_switch_camera);
        callingLayout = findViewById(R.id.calling_layout);
        tvCallingStatus = findViewById(R.id.tv_calling_status);
        tvCalleeName = findViewById(R.id.tv_callee_name);
        tvCallingType = findViewById(R.id.tv_calling_type);
        btnCancelCall = findViewById(R.id.btn_cancel_call);
        btnCall.setOnClickListener(v -> startCall());
        btnHangup.setOnClickListener(v -> hangup());
        btnSwitchCamera.setOnClickListener(v -> switchCamera());
        btnCancelCall.setOnClickListener(v -> hangup());
        if (targetUsername != null) {
            tvRemoteUser.setText(targetUsername);
            tvCalleeName.setText(targetUsername);
        }
        btnCall.setVisibility(View.GONE);
        if (!isIncomingCall) {
            showCallingUI();
        } else {
            showVideoUI();
        }
    }
    private void showCallingUI() {
        callingLayout.setVisibility(View.VISIBLE);
        remoteVideoView.setVisibility(View.GONE);
        localVideoView.setVisibility(View.GONE);
        btnHangup.setVisibility(View.GONE);
        btnSwitchCamera.setVisibility(View.GONE);
    }
    private void showVideoUI() {
        callingLayout.setVisibility(View.GONE);
        remoteVideoView.setVisibility(View.VISIBLE);
        if (CallMode.VIDEO.getValue().equals(callMode)) {
            localVideoView.setVisibility(View.VISIBLE);
            btnSwitchCamera.setVisibility(View.VISIBLE);
        } else {
            localVideoView.setVisibility(View.GONE);
            btnSwitchCamera.setVisibility(View.GONE);
        }
        
        btnHangup.setVisibility(View.VISIBLE);
    }
    private void initVideoViews() {
        if (webRTCManager != null) {
            localVideoView.init(webRTCManager.getEglBase().getEglBaseContext(), null);
            remoteVideoView.init(webRTCManager.getEglBase().getEglBaseContext(), null);
        }
    }
    private void checkPermissions() {
        PermissionX.init(this)
                .permissions(Constants.REQUIRED_PERMISSIONS)
                .request((allGranted, grantedList, deniedList) -> {
                    if (allGranted) {
                        bindWebSocketService();
                        registerWebSocketReceiver();
                    } else {
                        Toast.makeText(this, "需要相机和麦克风权限才能进行通话", Toast.LENGTH_SHORT).show();
                        finish();
                    }
                });
    }
    private void bindWebSocketService() {
        Intent intent = new Intent(this, WebSocketService.class);
        bindService(intent, webSocketServiceConnection, Context.BIND_AUTO_CREATE);
    }
    private void registerWebSocketReceiver() {
        IntentFilter filter = new IntentFilter(Constants.ACTION_WEBSOCKET_MESSAGE);
        LocalBroadcastManager.getInstance(this).registerReceiver(webSocketReceiver, filter);
    }
    private void handleWebSocketMessage(String message) {
        try {
            CommunicationMessage commMessage = CommunicationMessage.fromJson(message);
            String type = commMessage.getType();
            if (MessageType.OFFER.getValue().equals(type)) {
                webRTCManager.handleOffer(commMessage.getSdp(), commMessage.getMode());
            } else if (MessageType.ANSWER.getValue().equals(type)) {
                webRTCManager.handleAnswer(commMessage.getSdp());
            } else if (MessageType.ICE.getValue().equals(type)) {
                webRTCManager.handleIceCandidate(
                        commMessage.getSdpMid(),
                        commMessage.getSdpMLineIndex(),
                        commMessage.getCandidate());
            } else if (MessageType.CALL_BACK.getValue().equals(type)) {
                if ("1".equals(commMessage.getMsg())) {
                    runOnUiThread(() -> {
                        tvCallingStatus.setText("正在连接...");
                    });
                    webRTCManager.createOffer();
                } else {
                    runOnUiThread(() -> {
                        Toast.makeText(this, "对方拒绝了通话", Toast.LENGTH_SHORT).show();
                        hangup();
                    });
                }
            } else if (MessageType.HANGUP.getValue().equals(type)) {
                runOnUiThread(() -> {
                    Toast.makeText(this, "对方已挂断", Toast.LENGTH_SHORT).show();
                    hangup();
                });
            }
        } catch (JSONException e) {
            Log.e(TAG, "Failed to parse WebSocket message", e);
        }
    }
    private void startCall() {
        if (targetUser != null && !targetUser.isEmpty()) {
            webRTCManager.startCall(targetUser);
        } else {
            Toast.makeText(this, "未指定通话对象", Toast.LENGTH_SHORT).show();
            finish();
        }
    }
    private void hangup() {
        if (webRTCManager != null) {
            webRTCManager.hangup();
        }
        if (localVideoView != null) {
            localVideoView.clearImage();
        }
        if (remoteVideoView != null) {
            remoteVideoView.clearImage();
        }
        finish();
    }
    private void switchCamera() {
        if (webRTCManager != null) {
            webRTCManager.switchCamera();
        }
    }
    @Override
    public void onLocalVideoReady(VideoTrack videoTrack) {
        runOnUiThread(() -> {
            videoTrack.addSink(localVideoView);
        });
    }
    @Override
    public void onRemoteVideoReady(VideoTrack videoTrack) {
        runOnUiThread(() -> {
            videoTrack.addSink(remoteVideoView);
        });
    }
    @Override
    public void onCallConnected() {
        runOnUiThread(() -> {
            showVideoUI();
        });
    }
    @Override
    public void onCallDisconnected() {
        runOnUiThread(() -> {
            Toast.makeText(this, "通话已结束", Toast.LENGTH_SHORT).show();
            finish();
        });
    }
    @Override
    public void onError(String error) {
        runOnUiThread(() -> {
            Toast.makeText(this, "通话错误: " + error, Toast.LENGTH_SHORT).show();
        });
    }
    @Override
    protected void onDestroy() {
        if (isWebSocketServiceBound) {
            unbindService(webSocketServiceConnection);
            isWebSocketServiceBound = false;
        }
        LocalBroadcastManager.getInstance(this).unregisterReceiver(webSocketReceiver);
        if (webRTCManager != null) {
            webRTCManager.release();
        }
        super.onDestroy();
    }
} 